package cn.rkylin.oms.push.adapter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.taobao.api.DefaultTaobaoClient;
import com.taobao.api.FileItem;
import com.taobao.api.TaobaoClient;
import com.taobao.api.request.ItemQuantityUpdateRequest;
import com.taobao.api.request.ItemUpdateDelistingRequest;
import com.taobao.api.request.ItemUpdateListingRequest;
import com.taobao.api.request.LogisticsConsignResendRequest;
import com.taobao.api.request.LogisticsDummySendRequest;
import com.taobao.api.request.LogisticsOfflineSendRequest;
import com.taobao.api.request.LogisticsOnlineSendRequest;
import com.taobao.api.request.RefundRefuseRequest;
import com.taobao.api.request.RpRefundReviewRequest;
import com.taobao.api.request.RpRefundsAgreeRequest;
import com.taobao.api.request.RpReturngoodsAgreeRequest;
import com.taobao.api.request.TradeMemoAddRequest;
import com.taobao.api.request.TradeMemoUpdateRequest;
import com.taobao.api.response.ItemQuantityUpdateResponse;
import com.taobao.api.response.ItemUpdateDelistingResponse;
import com.taobao.api.response.ItemUpdateListingResponse;
import com.taobao.api.response.LogisticsConsignResendResponse;
import com.taobao.api.response.LogisticsDummySendResponse;
import com.taobao.api.response.LogisticsOfflineSendResponse;
import com.taobao.api.response.LogisticsOnlineSendResponse;
import com.taobao.api.response.RefundRefuseResponse;
import com.taobao.api.response.RpRefundReviewResponse;
import com.taobao.api.response.RpRefundsAgreeResponse;
import com.taobao.api.response.RpReturngoodsAgreeResponse;
import com.taobao.api.response.TradeMemoAddResponse;
import com.taobao.api.response.TradeMemoUpdateResponse;

import cn.rkylin.core.IDataBaseFactory;
import cn.rkylin.oms.common.dto.DBLog;
import cn.rkylin.oms.common.utils.LogUtil;
import cn.rkylin.oms.ectrade.vo.SystemConsignmentVO;
import cn.rkylin.oms.push.controller.PushItemController;
import cn.rkylin.oms.push.response.RefundBatchAgreeInfo;
import cn.rkylin.oms.refund.domain.taobao.TopRefund;
import cn.rkylin.oms.refund.vo.RefundVO;
import cn.rkylin.oms.system.shop.domain.Shop;

/**
 * TaobaoPushVisitor
 *
 * @author jipengcheng
 */
@Service("taobaoPushVisitor")
public class TaobaoPushVisitor extends PushVisitor {

    // 数据库访问对象
    @Autowired
    private IDataBaseFactory dao;

    @Autowired
    private LogUtil logUtil;

    /**
     * 系统发货
     *
     * @param shopId      店铺ID
     * @param ecItemCode  平台商品编码
     * @param ecTradeCode 平台交易单号
     * @param ecSkuCode   平台规格编码
     * @return
     */
    public Map<String, Object> pushSystemConsignment(Shop shop, String ecItemCode, String ecTradeCode, String ecSkuCode,
                                                     String shipTime) {

        Map<String, Object> returnMap = new HashMap<String, Object>();

        try {

            // 更新系统发货状态
            SystemConsignmentVO parameters = new SystemConsignmentVO();
            parameters.setShopId(shop.getShopId());
            parameters.setEcItemCode(ecItemCode);
            parameters.setEcTradeCode(ecTradeCode);
            parameters.setEcSkuCode(ecSkuCode);
            parameters.setShipTime(shipTime);

            int i = dao.update("updateSystemConsignmentStatus", parameters);
            if (i > 0) {
                returnMap.put("success", "y");
                returnMap.put("msg", "");
            } else {
                returnMap.put("success", "n");
                returnMap.put("msg", "updateSystemConsignmentStatus failed");
            }

        } catch (Exception e) {
            e.printStackTrace();
            returnMap.put("success", "n");
            returnMap.put("msg", e.getMessage());
        }

        return returnMap;
    }

    /**
     * 自己联系物流（线下物流）发货
     *
     * @param shop        网店对象
     * @param ecTradeCode 平台交易编码
     * @param lgstNo      物流单号
     * @param lgstCode    物流公司编码
     * @return 结果对象
     */
    @Override
    public Map<String, Object> pushTradeOfflineSend(Shop shop, String ecTradeCode, String lgstNo, String lgstCode) throws Exception {
        Map<String, Object> returnMap = new HashMap<String, Object>();
        String strError = "";

        Long tid = Long.valueOf(ecTradeCode);

        // taobao.logistics.offline.send
        TaobaoClient client = new DefaultTaobaoClient(shop.getApiUrl(), shop.getAppKey(), shop.getAppSecret());
        LogisticsOfflineSendRequest req = new LogisticsOfflineSendRequest();
        req.setTid(tid);
        req.setCompanyCode(lgstCode);
        req.setOutSid(lgstNo);
        LogisticsOfflineSendResponse rsp = client.execute(req, shop.getSessionKey());
        // 记录日志
        logUtil.info(new DBLog(ecTradeCode, "top_api", "taobao.logistics.offline.send", rsp.getBody()));
        if (rsp.getShipping() == null || !rsp.isSuccess()) {
            if (StringUtils.isNotBlank(rsp.getSubMsg())) {
                strError = rsp.getSubMsg();
            } else {
                strError = rsp.getMsg();
            }
            returnMap.put("success", "n");
            returnMap.put("msg", strError);
        } else {
            returnMap.put("success", "y");
            returnMap.put("msg", "");
        }
        return returnMap;
    }

    /**
     * 商品上架
     *
     * @param shop       网店对象
     * @param ecItemCode 平台商品编码
     * @param stockCount 库存数量
     * @return 结果对象
     */
    @Override
    public Map<String, Object> pushItemListing(Shop shop, String ecItemCode, String stockCount) throws Exception {
        Map<String, Object> returnMap = new HashMap<String, Object>();
        String strError = "";
        try {

            Long numIid = Long.valueOf(ecItemCode);

            // taobao.item.update.listing
            TaobaoClient client = new DefaultTaobaoClient(shop.getApiUrl(), shop.getAppKey(), shop.getAppSecret());
            ItemUpdateListingRequest req = new ItemUpdateListingRequest();
            req.setNumIid(numIid);
            req.setNum(Long.valueOf(stockCount));

            ItemUpdateListingResponse rsp = client.execute(req, shop.getSessionKey());
            if (!rsp.isSuccess()) {
                if (StringUtils.isNotBlank(rsp.getSubMsg())) {
                    strError = rsp.getSubMsg();
                } else {
                    strError = rsp.getMsg();
                }
                returnMap.put("success", "n");
                returnMap.put("msg", strError);
            } else {
                returnMap.put("success", "y");
                returnMap.put("msg", "");
            }
        } catch (Exception e) {
            e.printStackTrace();
            returnMap.put("success", "n");
            returnMap.put("msg", e.getMessage());
        }
        return returnMap;
    }

    /**
     * 商品下架
     *
     * @param shop       网店对象
     * @param ecItemCode 平台商品编码
     * @return 结果对象
     */
    @Override
    public Map<String, Object> pushItemDeListing(Shop shop, String ecItemCode) throws Exception {

        Map<String, Object> returnMap = new HashMap<String, Object>();
        String strError = "";
        try {

            Long numIid = Long.valueOf(ecItemCode);

            // taobao.item.update.delisting
            TaobaoClient client = new DefaultTaobaoClient(shop.getApiUrl(), shop.getAppKey(), shop.getAppSecret());
            ItemUpdateDelistingRequest req = new ItemUpdateDelistingRequest();
            req.setNumIid(numIid);

            ItemUpdateDelistingResponse rsp = client.execute(req, shop.getSessionKey());

            if (!rsp.isSuccess()) {
                if (StringUtils.isNotBlank(rsp.getSubMsg())) {
                    strError = rsp.getSubMsg();
                } else {
                    strError = rsp.getMsg();
                }
                strError = rsp.getBody();
                returnMap.put("success", "n");
                returnMap.put("msg", strError);
            } else {
                returnMap.put("success", "y");
                returnMap.put("msg", "");
            }
        } catch (Exception e) {
            e.printStackTrace();
            returnMap.put("success", "n");
            returnMap.put("msg", e.getMessage());
        }
        return returnMap;
    }

    /**
     * 批量同意退款
     *
     * @param shop          网店对象
     * @param ecRefundCodes 平台退款编号, 按照 ","号分割
     * @param code          短信验证码
     * @return 结果对象
     */
    @Override
    public Map<String, Object> pushRefundBatchAgree(Shop shop, String ecRefundCodes, String code) {

        Map<String, Object> returnMap = new HashMap<String, Object>();
        List<RefundBatchAgreeInfo> rarbList = new ArrayList<RefundBatchAgreeInfo>();

        List<String> refundids = new ArrayList<String>();

        String strError = "";
        try {

            for (String strTemp : ecRefundCodes.split(",")) {
                refundids.add(strTemp);
            }

            // 批量退款不能超过30条
            if (refundids.size() > 30) {
                returnMap.put("success", "n");
                returnMap.put("msg", "批量退款不能超过30条");
                return returnMap;
            }

            Map<String, Object> reqParams = new HashMap<String, Object>();
            reqParams.put("shopId", shop.getShopId());
            reqParams.put("refundIds", refundids);

            List<TopRefund> topRefundList = dao.findList("selectByRefundIdTopRefundList", reqParams);
            if (topRefundList == null || topRefundList.size() < 1) {
                returnMap.put("success", "n");
                returnMap.put("msg", "没有满足退款的订单数据");
                return returnMap;
            }

            TaobaoClient client = new DefaultTaobaoClient(shop.getApiUrl(), shop.getAppKey(), shop.getAppSecret());
            // 批量退款前，将所要退款的单据审核
            for (TopRefund topRefund : topRefundList) {

                // taobao.rp.refund.review
                RpRefundReviewRequest req = new RpRefundReviewRequest();
                req.setRefundId(topRefund.getRefundId());
                if (StringUtils.isNotEmpty(topRefund.getRefundPhase())) {
                    req.setRefundPhase(topRefund.getRefundPhase());
                }
                req.setRefundVersion(topRefund.getRefundVersion());
                req.setMessage("批量可退款");
                req.setOperator("管理员");
                req.setResult(true);

                RpRefundReviewResponse rsp = client.execute(req, shop.getSessionKey());
            }

            // 调用api执行批量退款操作
            String refundInfos = "";
            String refundInfosTo = "";
            // 售后退款的单号拼串
            String refundIdPhase = "";
            for (TopRefund topRefund : topRefundList) {

                // 暂时默认为天猫 B店
                refundInfos += topRefund.getRefundId() + "|" + topRefund.getRefundFee() + "|"
                        + topRefund.getRefundVersion() + "|" + topRefund.getRefundPhase();

                refundInfosTo += refundInfos + ",";

                if (topRefund.getRefundPhase().equals("aftersale")) {
                    refundIdPhase += topRefund.getRefundId() + ",";
                }
            }

            // taobao.rp.refunds.agree
            RpRefundsAgreeRequest req = new RpRefundsAgreeRequest();
            if (StringUtils.isNotEmpty(code)) {
                req.setCode(code);

            }
            req.setRefundInfos(refundInfosTo.substring(0, refundInfosTo.length() - 1));
            RpRefundsAgreeResponse rsp = client.execute(req, shop.getSessionKey());

            // 获取短信验证码
            if (StringUtils.isEmpty(code)) {
                // 如果Message是空的，返回错误
                if (rsp.getSucc() == null) {
                    returnMap.put("success", "n");
                    returnMap.put("msg", rsp.getMsg());
                    return returnMap;
                }
                if (rsp.getSucc() == false) {
                    if (StringUtils.isNotBlank(rsp.getSubMsg())) {
                        strError = rsp.getSubMsg();
                    } else {
                        strError = rsp.getMsg();
                    }
                    returnMap.put("success", "n");
                    returnMap.put("msg", strError);
                    return returnMap;
                }
            }

            // 获取验证码成功后，同意批量退款
            if (StringUtils.isNotEmpty(code)) {
                if (rsp.getSucc() == false) {
                    if (StringUtils.isNotBlank(rsp.getSubMsg())) {
                        strError = rsp.getSubMsg();
                    } else {
                        strError = rsp.getMsg();
                    }
                    returnMap.put("success", "n");
                    returnMap.put("msg", strError);
                    return returnMap;
                } else {

                    for (com.taobao.api.domain.RefundMappingResult result : rsp.getResults()) {
                        String refId = result.getRefundId().toString();
                        long refundId = 0;

                        Boolean bTemp = false;

                        for (TopRefund topRefund : topRefundList) {
                            if (topRefund.getRefundId().toString().equals(refId)) {
                                bTemp = true;
                                break;
                            }
                        }

                        if (bTemp) {
                            refundId = Long.valueOf(refId);
                        } else {
                            // 售后类型
                            // 售后类型的退款单号
                            String[] strRefund = refundIdPhase.split(",");
                            for (int i = 0; strRefund.length > 0; i++) {
                                String codeadd = "";
                                // 本次退款的售后退款单号截取处理
                                String code1 = strRefund[i].substring(0, 1);
                                String code2 = strRefund[i].substring(3, refId.length() - 3);
                                codeadd = code1 + code2;
                                // 截取后的退款单号与本次退款是售后类型的匹配
                                if (refId.equals(codeadd)) {
                                    refundId = Long.valueOf(strRefund[i]);
                                }
                            }
                        }

                        // 返回退款单批量处理的结果
                        RefundBatchAgreeInfo rarb = new RefundBatchAgreeInfo();
                        rarb.setRefundId(String.valueOf(refundId));
                        rarb.setSuccess(result.getSucc() ? "y" : "n");
                        rarb.setMessage(result.getMessage());
                        if (result.getSucc()) {
                            rarb.setFinallyYn("Y");
                        } else {
                            rarb.setFinallyYn("N");
                        }
                        rarbList.add(rarb);
                    }
                }
            }
            returnMap.put("success", "y");
            returnMap.put("msg", "");
            returnMap.put("rarbList", rarbList);

        } catch (Exception e) {
            e.printStackTrace();
            returnMap.put("success", "n");
            returnMap.put("msg", e.getMessage());
        }
        return returnMap;
    }

    /**
     * 拒绝退款
     *
     * @param shop
     * @param ecRefundCode   退款单号
     * @param refuseMessage  拒绝退款时的说明信息，长度2-200
     * @param refuseReasonId 拒绝原因编号，会提供用户拒绝原因列表供选择
     * @param refusePath     拒绝退款时的退款凭证对应的本地绝对路径，一般是卖家拒绝退款时使用的发货凭证，最大长度130000字节，支持的图片格式：
     *                       GIF, JPG, PNG支持的文件类型：gif,jpg,png
     * @return
     */
    @Override
    public Map<String, Object> pushRefundRefuse(Shop shop, String ecRefundCode, String refuseMessage,
                                                String refuseReasonId, String refusePath) {
        Map<String, Object> returnMap = new HashMap<String, Object>();
        String strError = "";
        try {

            Long refundId = Long.valueOf(ecRefundCode);

            Map<String, Object> reqMap = new HashMap<String, Object>();
            reqMap.put("refundId", refundId);

            List<TopRefund> refundList = dao.findList("selectByRefundIdTopRefund", reqMap);
            if (refundList == null || refundList.size() < 1) {
                returnMap.put("success", "n");
                returnMap.put("msg", "获取退款阶段  selectByRefundIdTopRefund is null");
                return returnMap;
            }
            TopRefund modelTopRefund = refundList.get(0);
            String refundPhase = modelTopRefund.getRefundPhase();
            long refundVersion = modelTopRefund.getRefundVersion();

            // taobao.refund.refuse
            TaobaoClient client = new DefaultTaobaoClient(shop.getApiUrl(), shop.getAppKey(), shop.getAppSecret());
            RefundRefuseRequest req = new RefundRefuseRequest();
            req.setRefundId(refundId);
            req.setRefuseMessage(refuseMessage);
            req.setRefundPhase(refundPhase);
            req.setRefundVersion(refundVersion);
            if (refundVersion != 0) {
                req.setRefuseReasonId(Long.valueOf(refuseReasonId));
            }
            if (StringUtils.isNotEmpty(refusePath)) {
                req.setRefuseProof(new FileItem(refusePath));
            }
            RefundRefuseResponse rsp = client.execute(req, shop.getSessionKey());
            if (rsp.isSuccess() == false) {
                if (StringUtils.isNotEmpty(rsp.getSubMsg())) {
                    strError = rsp.getSubMsg();
                } else {
                    strError = rsp.getMsg();
                }
                returnMap.put("success", "n");
                returnMap.put("msg", strError);
            } else {
                returnMap.put("success", "y");
                returnMap.put("msg", "");
            }

        } catch (Exception e) {
            e.printStackTrace();
            returnMap.put("success", "n");
            returnMap.put("msg", e.getMessage());
        }

        return returnMap;
    }

    /**
     * 卖家同意退货
     *
     * @param shop
     * @param ecRefundCode    退款单编号
     * @param name            卖家姓名，淘宝退款为必填项。
     * @param address         卖家提供的退货地址，淘宝退款为必填项。
     * @param post            卖家提供的退货地址的邮编，淘宝退款为必填项
     * @param tel             卖家座机，淘宝退款为必填项。
     * @param mobile          卖家手机，淘宝退款为必填项。
     * @param remark          卖家退货留言，天猫退款为必填项。
     * @param sellerAddressId 卖家收货地址编号，天猫退款为必填项。
     * @return
     */
    @Override
    public Map<String, Object> pushReturnGoodsAgree(Shop shop, String ecRefundCode, String name, String address,
                                                    String post, String tel, String mobile, String remark, String sellerAddressId) {

        Map<String, Object> returnMap = new HashMap<String, Object>();
        String strError = "";
        try {

            Long refundId = Long.valueOf(ecRefundCode);

            Map<String, Object> reqMap = new HashMap<String, Object>();
            reqMap.put("refundId", refundId);

            List<TopRefund> refundList = dao.findList("selectByRefundIdTopRefund", reqMap);
            if (refundList == null || refundList.size() < 1) {
                returnMap.put("success", "n");
                returnMap.put("msg", "获取退款阶段  selectByRefundIdTopRefund is null");
                return returnMap;
            }
            TopRefund modelTopRefund = refundList.get(0);
            String refundPhase = modelTopRefund.getRefundPhase();
            long refundVersion = modelTopRefund.getRefundVersion();

            // taobao.rp.returngoods.agree
            TaobaoClient client = new DefaultTaobaoClient(shop.getApiUrl(), shop.getAppKey(), shop.getAppSecret());
            RpReturngoodsAgreeRequest req = new RpReturngoodsAgreeRequest();
            req.setRefundId(refundId);
            req.setName(name);
            req.setAddress(address);
            req.setPost(post);
            req.setTel(tel);
            req.setMobile(mobile);
            req.setRemark(remark);
            req.setRefundPhase(refundPhase);
            req.setRefundVersion(refundVersion);

            RpReturngoodsAgreeResponse rsp = client.execute(req, shop.getSessionKey());
            // 操作错误, 返回错误结果
            if (rsp.isSuccess() == false) {
                if (StringUtils.isNotEmpty(rsp.getSubMsg())) {
                    strError = rsp.getSubMsg();
                } else {
                    strError = rsp.getMsg();
                }
                returnMap.put("success", "n");
                returnMap.put("msg", strError);
            } else {
                returnMap.put("success", "y");
                returnMap.put("msg", "");
            }
        } catch (Exception e) {
            e.printStackTrace();
            returnMap.put("success", "n");
            returnMap.put("msg", e.getMessage());
        }
        return returnMap;
    }

    /**
     * 审核退款单
     *
     * @param shop         网店对象
     * @param ecRefundCode 平台退款编号
     * @param erpStatus    审核状态 已审核/未审核
     * @return 结果对象
     */
    @Override
    public Map<String, Object> pushRefundAppr(Shop shop, String ecRefundCode, String erpStatus) {

        Map<String, Object> returnMap = new HashMap<String, Object>();

        try {

            // 更新平台退款单信息
            RefundVO parameters = new RefundVO();
            parameters.setPrjId(shop.getPrjId());
            parameters.setShopId(shop.getShopId());
            parameters.setEcRefundCode(ecRefundCode);
            parameters.setErpStatus(erpStatus);

            int i = dao.update("updateByRefundCodeRefund", parameters);
            if (i > 0) {
                returnMap.put("success", "y");
                returnMap.put("msg", "");
            } else {
                returnMap.put("success", "n");
                returnMap.put("msg", "updateByRefundCodeRefund failed");
            }

        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
            returnMap.put("success", "n");
            returnMap.put("msg", e.getMessage());
        }

        return returnMap;
    }

    /**
     * 宝贝/SKU库存修改(商品)
     *
     * @param shop       网店对象
     * @param ecItemCode 平台退款编号
     * @param stockCount 库存数量
     * @return 结果对象
     */
    @Override
    public Map<String, Object> pushItemQuantityUpdate(Shop shop, String ecItemCode, String skuId, String stockCount) {

        Map<String, Object> returnMap = new HashMap<String, Object>();
        String strError = "";
        try {

            Long numIid = Long.valueOf(ecItemCode);
            Long quantity = Long.valueOf(stockCount);

            // taobao.item.quantity.update
            TaobaoClient client = new DefaultTaobaoClient(shop.getApiUrl(), shop.getAppKey(), shop.getAppSecret());
            ItemQuantityUpdateRequest req = new ItemQuantityUpdateRequest();

            // 商品数字ID，必填参数
            req.setNumIid(numIid);

            // 规格ID，可选
            if (skuId != null) {
                req.setSkuId(Long.parseLong(skuId));
            }

            // 库存修改值，必选
            req.setQuantity(quantity);

            ItemQuantityUpdateResponse rsp = client.execute(req, shop.getSessionKey());

            // 操作错误，返回错误结果
            if (!rsp.isSuccess()) {
                if (StringUtils.isNotBlank(rsp.getSubMsg())) {
                    strError = rsp.getSubMsg();
                } else {
                    strError = rsp.getMsg();
                }
                returnMap.put("success", "n");
                returnMap.put("msg", strError);
            } else {
                returnMap.put("success", "y");
                returnMap.put("msg", "");
            }

        } catch (Exception e) {
            e.printStackTrace();
            returnMap.put("success", "n");
            returnMap.put("msg", e.getMessage());
        }
        return returnMap;
    }

    /**
     * 宝贝/SKU库存修改(SKU)
     *
     * @param shop       网店对象
     * @param ecItemCode 平台退款编号
     * @param ecSkuCode  平台规格编码
     * @param stockCount 库存数量
     * @return 结果对象
     */
    @Override
    public Map<String, Object> pushSkuQuantityUpdate(Shop shop, String ecItemCode, String ecSkuCode,
                                                     String stockCount) {

        Map<String, Object> returnMap = new HashMap<String, Object>();
        String strError = "";
        try {

            Long numIid = Long.valueOf(ecItemCode);
            Long skuId = Long.valueOf(ecSkuCode);
            Long quantity = Long.valueOf(stockCount);

            // taobao.item.quantity.update
            TaobaoClient client = new DefaultTaobaoClient(shop.getApiUrl(), shop.getAppKey(), shop.getAppSecret());
            ItemQuantityUpdateRequest req = new ItemQuantityUpdateRequest();

            // 商品数字ID，必填参数
            req.setNumIid(numIid);

            // 要操作的SKU的数字ID，可选
            req.setSkuId(skuId);

            // 库存修改值，必选
            if (quantity > 0) {
                req.setQuantity(quantity);
            } else {
                req.setQuantity(Long.valueOf(0));
            }

            // 库存更新方式，可选
            req.setType(Long.valueOf(1));

            ItemQuantityUpdateResponse rsp = client.execute(req, shop.getSessionKey());

            // 操作错误，返回错误结果
            if (!rsp.isSuccess()) {
                if (StringUtils.isNotBlank(rsp.getSubMsg())) {
                    strError = rsp.getSubMsg();
                } else {
                    strError = rsp.getMsg();
                }
                returnMap.put("success", "n");
                returnMap.put("msg", strError);
            } else {
                returnMap.put("success", "y");
                returnMap.put("msg", "");
            }

        } catch (Exception e) {
            e.printStackTrace();
            returnMap.put("success", "n");
            returnMap.put("msg", e.getMessage());
        }
        return returnMap;
    }

    /**
     * 对一笔交易添加备注
     *
     * @param tid  交易编号
     * @param memo 备注
     * @param flag 交易备注旗帜，可选值为：0(灰色), 1(红色), 2(黄色), 3(绿色), 4(蓝色), 5(粉红色)，默认值为0
     * @return
     * @throws Exception
     */
    private Map<String, Object> pushTradeMemoAdd(Shop shop, Long tid, String memo, Long flag) throws Exception {
        Map<String, Object> returnMap = new HashMap<String, Object>();
        String strError = "";
        try {
            TaobaoClient client = new DefaultTaobaoClient(shop.getApiUrl(), shop.getAppKey(), shop.getAppSecret());
            TradeMemoAddRequest req = new TradeMemoAddRequest();
            req.setTid(tid);
            req.setMemo(memo);
            req.setFlag(flag);
            TradeMemoAddResponse rsp = client.execute(req, shop.getSessionKey());
            // 操作错误，返回错误结果
            if (!rsp.isSuccess()) {
                if (StringUtils.isNotBlank(rsp.getSubMsg())) {
                    strError = rsp.getSubMsg();
                } else {
                    strError = rsp.getMsg();
                }
                returnMap.put("success", "n");
                returnMap.put("msg", strError);
            } else {
                returnMap.put("success", "y");
                returnMap.put("msg", "");
            }
        } catch (Exception e) {
            e.printStackTrace();
            returnMap.put("success", "n");
            returnMap.put("msg", e.getMessage());
        }
        return returnMap;

    }

    /**
     * 修改一笔交易备注
     *
     * @param tid  交易编号
     * @param memo 备注
     * @param flag 交易备注旗帜，可选值为：0(灰色), 1(红色), 2(黄色), 3(绿色), 4(蓝色), 5(粉红色)，默认值为0
     * @return
     * @throws Exception
     */
    public Map<String, Object> pushTradeMemo(Shop shop, Long tid, String memo, Long flag) throws Exception {
        Map<String, Object> returnMap = new HashMap<String, Object>();
        String strError = "";
        try {
            TaobaoClient client = new DefaultTaobaoClient(shop.getApiUrl(), shop.getAppKey(), shop.getAppSecret());
            TradeMemoUpdateRequest req = new TradeMemoUpdateRequest();
            req.setTid(tid);
            req.setMemo(memo);
            req.setFlag(flag);
//			req.setReset(false);
            TradeMemoUpdateResponse rsp = client.execute(req, shop.getSessionKey());

            logUtil.info(new DBLog(String.valueOf(tid), "top_api", "taobao.trade.memo.update", rsp.getBody()));

            // 操作错误，返回错误结果
            if (!rsp.isSuccess()) {
                if (StringUtils.isNotBlank(rsp.getSubMsg())) {
                    strError = rsp.getSubMsg();
                } else {
                    strError = rsp.getMsg();
                }
                returnMap.put("success", "n");
                returnMap.put("msg", strError);
            } else {
                returnMap.put("success", "y");
                returnMap.put("msg", "");
            }

        } catch (Exception e) {
            e.printStackTrace();
            returnMap.put("success", "n");
            returnMap.put("msg", e.getMessage());
        }
        return returnMap;
    }

    /**
     * 在线订单发货处理（支持货到付款）
     *
     * @param tid          交易号
     * @param out_sid      运单号.具体一个物流公司的真实运单号码
     * @param company_code 物流公司代码.如"POST"就代表中国邮政,"ZJS"就代表宅急送
     * @return
     * @throws Exception
     */
    private Map<String, Object> pushTradeOnlineSend(Shop shop, Long tid, String out_sid, String company_code)
            throws Exception {
        Map<String, Object> returnMap = new HashMap<String, Object>();
        String strError = "";
        try {
            TaobaoClient client = new DefaultTaobaoClient(shop.getApiUrl(), shop.getAppKey(), shop.getAppSecret());
            LogisticsOnlineSendRequest req = new LogisticsOnlineSendRequest();
            req.setTid(tid);
            req.setCompanyCode(company_code);
            if (StringUtils.isNotBlank(out_sid)) {
                req.setOutSid(out_sid);
            }
            LogisticsOnlineSendResponse rsp = client.execute(req, shop.getSessionKey());
            if (rsp.getShipping() == null || !rsp.isSuccess()) {
                if (StringUtils.isNotBlank(rsp.getSubMsg())) {
                    strError = rsp.getSubMsg();
                } else {
                    strError = rsp.getMsg();
                }
                returnMap.put("success", "n");
                returnMap.put("msg", strError);
            } else {
                returnMap.put("success", "y");
                returnMap.put("msg", "");
            }

        } catch (Exception e) {
            e.printStackTrace();
            returnMap.put("success", "n");
            returnMap.put("msg", e.getMessage());
        }
        return returnMap;

    }

    /**
     * 在线订单发货处理（支持货到付款）
     *
     * @param tid          交易号
     * @param out_sid      运单号.具体一个物流公司的真实运单号码
     * @param company_code 物流公司代码.如"POST"就代表中国邮政,"ZJS"就代表宅急送
     * @param sub_tid
     * @return
     * @throws Exception
     */
    private Map<String, Object> pushTradeOnlineSend_Split(Shop shop, Long tid, String out_sid, String company_code,
                                                          String sub_tid) throws Exception {
        Map<String, Object> returnMap = new HashMap<String, Object>();
        String strError = "";
        try {
            TaobaoClient client = new DefaultTaobaoClient(shop.getApiUrl(), shop.getAppKey(), shop.getAppSecret());
            LogisticsOnlineSendRequest req = new LogisticsOnlineSendRequest();
            req.setTid(tid);
            req.setCompanyCode(company_code);
            if (StringUtils.isNotBlank(out_sid)) {
                req.setOutSid(out_sid);
            }
            req.setIsSplit(1L);
            String subtids = "";
            if (sub_tid != null) {
                String[] temp = sub_tid.split(",");
                for (int i = 0; i < temp.length; i++) {
                    if (i == 0) {
                        subtids = temp[i];
                    } else {
                        subtids = subtids + "," + temp[i];
                    }

                }
            }
            req.setSubTid(subtids);
            LogisticsOnlineSendResponse rsp = client.execute(req, shop.getSessionKey());
            if (rsp.getShipping() == null || !rsp.isSuccess()) {
                if (StringUtils.isNotBlank(rsp.getSubMsg())) {
                    strError = rsp.getSubMsg();
                } else {
                    strError = rsp.getMsg();
                }
                returnMap.put("success", "n");
                returnMap.put("msg", strError);
            } else {
                returnMap.put("success", "y");
                returnMap.put("msg", "");
            }

        } catch (Exception e) {
            e.printStackTrace();
            returnMap.put("success", "n");
            returnMap.put("msg", e.getMessage());
        }
        return returnMap;

    }

    /**
     * 自己联系物流（线下物流）发货
     *
     * @param tid          交易号
     * @param out_sid      运单号.具体一个物流公司的真实运单号码
     * @param company_code 物流公司代码.如"POST"就代表中国邮政,"ZJS"就代表宅急送
     * @return
     * @throws Exception
     */
    private Map<String, Object> pushTradeOfflineSend(Shop shop, Long tid, String out_sid, String company_code)
            throws Exception {
        Map<String, Object> returnMap = new HashMap<String, Object>();
        String strError = "";
        try {
            TaobaoClient client = new DefaultTaobaoClient(shop.getApiUrl(), shop.getAppKey(), shop.getAppSecret());
            LogisticsOfflineSendRequest req = new LogisticsOfflineSendRequest();
            req.setTid(tid);
            req.setCompanyCode(company_code);
            req.setOutSid(out_sid);
            LogisticsOfflineSendResponse rsp = client.execute(req, shop.getSessionKey());
            if (rsp.getShipping() == null || !rsp.isSuccess()) {
                if (StringUtils.isNotBlank(rsp.getSubMsg())) {
                    strError = rsp.getSubMsg();
                } else {
                    strError = rsp.getMsg();
                }
                returnMap.put("success", "n");
                returnMap.put("msg", strError);
            } else {
                returnMap.put("success", "y");
                returnMap.put("msg", "");
            }
        } catch (Exception e) {
            e.printStackTrace();
            returnMap.put("success", "n");
            returnMap.put("msg", e.getMessage());
        }
        return returnMap;

    }

    /**
     * 自己联系物流（线下物流）发货
     *
     * @param tid          交易号
     * @param out_sid      运单号.具体一个物流公司的真实运单号码
     * @param company_code 物流公司代码.如"POST"就代表中国邮政,"ZJS"就代表宅急送
     * @param sub_tid
     * @return
     * @throws Exception
     */
    private Map<String, Object> pushTradeOfflineSend_Split(Shop shop, Long tid, String out_sid, String company_code,
                                                           String sub_tid) throws Exception {
        Map<String, Object> returnMap = new HashMap<String, Object>();
        String strError = "";
        try {
            TaobaoClient client = new DefaultTaobaoClient(shop.getApiUrl(), shop.getAppKey(), shop.getAppSecret());
            LogisticsOfflineSendRequest req = new LogisticsOfflineSendRequest();
            req.setTid(tid);
            req.setCompanyCode(company_code);
            req.setOutSid(out_sid);
            String subtids = "";
            if (sub_tid != null) {
                String[] temp = sub_tid.split(",");
                for (int i = 0; i < temp.length; i++) {
                    if (i == 0) {
                        subtids = temp[i];
                    } else {
                        subtids = subtids + "," + temp[i];
                    }

                }
            }
            req.setIsSplit(1L);
            LogisticsOfflineSendResponse rsp = client.execute(req, shop.getSessionKey());
            if (rsp.getShipping() == null || !rsp.isSuccess()) {
                if (StringUtils.isNotBlank(rsp.getSubMsg())) {
                    strError = rsp.getSubMsg();
                } else {
                    strError = rsp.getMsg();
                }
                returnMap.put("success", "n");
                returnMap.put("msg", strError);
            } else {
                returnMap.put("success", "y");
                returnMap.put("msg", "");
            }
        } catch (Exception e) {
            e.printStackTrace();
            returnMap.put("success", "n");
            returnMap.put("msg", e.getMessage());
        }
        return returnMap;

    }

    /**
     * 修改物流公司和运单号
     *
     * @param tid          交易号
     * @param out_sid      运单号.具体一个物流公司的真实运单号码
     * @param company_code 物流公司代码.如"POST"就代表中国邮政,"ZJS"就代表宅急送
     * @return
     * @throws Exception
     */
    private Map<String, Object> pushTradeConsignResend(Shop shop, Long tid, String out_sid, String company_code)
            throws Exception {
        Map<String, Object> returnMap = new HashMap<String, Object>();
        String strError = "";
        try {
            TaobaoClient client = new DefaultTaobaoClient(shop.getApiUrl(), shop.getAppKey(), shop.getAppSecret());
            LogisticsConsignResendRequest req = new LogisticsConsignResendRequest();
            req.setTid(tid);
            req.setCompanyCode(company_code);
            req.setOutSid(out_sid);
            LogisticsConsignResendResponse rsp = client.execute(req, shop.getSessionKey());
            if (rsp.getShipping() == null || !rsp.isSuccess()) {
                if (StringUtils.isNotBlank(rsp.getSubMsg())) {
                    strError = rsp.getSubMsg();
                } else {
                    strError = rsp.getMsg();
                }
                returnMap.put("success", "n");
                returnMap.put("msg", strError);
            } else {
                returnMap.put("success", "y");
                returnMap.put("msg", "");
            }
        } catch (Exception e) {
            e.printStackTrace();
            returnMap.put("success", "n");
            returnMap.put("msg", e.getMessage());
        }
        return returnMap;

    }

    /**
     * 无需物流（虚拟）发货处理
     *
     * @param tid 交易号
     * @return
     * @throws Exception
     */
    private Map<String, Object> pushTradeDummySend(Shop shop, Long tid) throws Exception {
        Map<String, Object> returnMap = new HashMap<String, Object>();
        String strError = "";
        try {
            TaobaoClient client = new DefaultTaobaoClient(shop.getApiUrl(), shop.getAppKey(), shop.getAppSecret());
            LogisticsDummySendRequest req = new LogisticsDummySendRequest();
            req.setTid(tid);
            LogisticsDummySendResponse rsp = client.execute(req, shop.getSessionKey());
            if (rsp.getShipping() == null || !rsp.isSuccess()) {
                if (StringUtils.isNotBlank(rsp.getSubMsg())) {
                    strError = rsp.getSubMsg();
                } else {
                    strError = rsp.getMsg();
                }
                returnMap.put("success", "n");
                returnMap.put("msg", strError);
            } else {
                returnMap.put("success", "y");
                returnMap.put("msg", "");
            }

        } catch (Exception e) {
            e.printStackTrace();
            returnMap.put("success", "n");
            returnMap.put("msg", e.getMessage());
        }
        return returnMap;

    }

}
